package com.rickpan.controller;

import com.rickpan.dto.common.ApiResponse;
import com.rickpan.service.FileUrlService;
import com.rickpan.storage.url.MinIOUrlGenerationService;
import com.rickpan.utils.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.Duration;
import java.util.List;
import java.util.Map;

/**
 * 文件 URL 管理控制器
 * 提供文件 URL 生成和管理的 API 接口
 */
@RestController
@RequestMapping("/api/files/urls")
public class FileUrlController {
    
    private static final Logger logger = LoggerFactory.getLogger(FileUrlController.class);
    
    @Autowired
    private FileUrlService fileUrlService;
    
    @Autowired(required = false)
    private MinIOUrlGenerationService minIOUrlGenerationService;
    
    /**
     * 生成文件下载 URL
     * GET /api/files/urls/{fileId}/download
     */
    @GetMapping("/{fileId}/download")
    public ApiResponse<String> generateDownloadUrl(
            @PathVariable Long fileId,
            @RequestParam(defaultValue = "3600") int expirationSeconds) {
        
        try {
            Long userId = SecurityUtils.getCurrentUserId();
            Duration expiration = Duration.ofSeconds(expirationSeconds);
            
            String url = fileUrlService.generateSecureDownloadUrl(userId, fileId, expiration);
            
            logger.info("生成下载URL: userId={}, fileId={}, 有效期={}秒", userId, fileId, expirationSeconds);
            
            return ApiResponse.success(url);
            
        } catch (Exception e) {
            logger.error("生成下载URL失败: fileId={}", fileId, e);
            return ApiResponse.error("生成下载URL失败: " + e.getMessage());
        }
    }
    
    /**
     * 生成文件预览 URL
     * GET /api/files/urls/{fileId}/preview
     */
    @GetMapping("/{fileId}/preview")
    public ApiResponse<String> generatePreviewUrl(
            @PathVariable Long fileId,
            @RequestParam(defaultValue = "1800") int expirationSeconds) {
        
        try {
            Long userId = SecurityUtils.getCurrentUserId();
            Duration expiration = Duration.ofSeconds(expirationSeconds);
            
            String url = fileUrlService.generateSecurePreviewUrl(userId, fileId, expiration);
            
            logger.info("生成预览URL: userId={}, fileId={}, 有效期={}秒", userId, fileId, expirationSeconds);
            
            return ApiResponse.success(url);
            
        } catch (Exception e) {
            logger.error("生成预览URL失败: fileId={}", fileId, e);
            return ApiResponse.error("生成预览URL失败: " + e.getMessage());
        }
    }
    
    /**
     * 批量生成文件下载 URL
     * POST /api/files/urls/batch/download
     */
    @PostMapping("/batch/download")
    public ApiResponse<Map<Long, String>> batchGenerateDownloadUrls(
            @RequestBody BatchUrlRequest request) {
        
        try {
            Long userId = SecurityUtils.getCurrentUserId();
            Duration expiration = Duration.ofSeconds(request.getExpirationSeconds());
            
            Map<Long, String> urls = fileUrlService.batchGenerateSecureDownloadUrls(
                userId, request.getFileIds(), expiration);
            
            logger.info("批量生成下载URL: userId={}, {} 个文件, 有效期={}秒", 
                       userId, request.getFileIds().size(), request.getExpirationSeconds());
            
            return ApiResponse.success(urls);
            
        } catch (Exception e) {
            logger.error("批量生成下载URL失败: fileIds={}", request.getFileIds(), e);
            return ApiResponse.error("批量生成下载URL失败: " + e.getMessage());
        }
    }
    
    /**
     * 批量生成文件预览 URL
     * POST /api/files/urls/batch/preview
     */
    @PostMapping("/batch/preview")
    public ApiResponse<Map<Long, String>> batchGeneratePreviewUrls(
            @RequestBody BatchUrlRequest request) {
        
        try {
            Long userId = SecurityUtils.getCurrentUserId();
            Duration expiration = Duration.ofSeconds(request.getExpirationSeconds());
            
            Map<Long, String> urls = fileUrlService.batchGenerateSecurePreviewUrls(
                userId, request.getFileIds(), expiration);
            
            logger.info("批量生成预览URL: userId={}, {} 个文件, 有效期={}秒", 
                       userId, request.getFileIds().size(), request.getExpirationSeconds());
            
            return ApiResponse.success(urls);
            
        } catch (Exception e) {
            logger.error("批量生成预览URL失败: fileIds={}", request.getFileIds(), e);
            return ApiResponse.error("批量生成预览URL失败: " + e.getMessage());
        }
    }
    
    /**
     * 刷新 URL（如果即将过期）
     * POST /api/files/urls/{fileId}/refresh
     */
    @PostMapping("/{fileId}/refresh")
    public ApiResponse<String> refreshUrl(
            @PathVariable Long fileId,
            @RequestParam String urlType) {
        
        try {
            Long userId = SecurityUtils.getCurrentUserId();
            
            if (!"download".equals(urlType) && !"preview".equals(urlType)) {
                return ApiResponse.error("无效的URL类型，支持: download, preview");
            }
            
            String url = fileUrlService.refreshUrlIfNeeded(userId, fileId, urlType);
            
            logger.info("刷新URL: userId={}, fileId={}, urlType={}", userId, fileId, urlType);
            
            return ApiResponse.success(url);
            
        } catch (Exception e) {
            logger.error("刷新URL失败: fileId={}, urlType={}", fileId, urlType, e);
            return ApiResponse.error("刷新URL失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取 URL 缓存统计信息（仅 MinIO 存储）
     * GET /api/files/urls/cache/stats
     */
    @GetMapping("/cache/stats")
    public ApiResponse<Object> getCacheStats() {
        try {
            if (minIOUrlGenerationService == null) {
                return ApiResponse.error("当前存储类型不支持URL缓存统计");
            }
            
            MinIOUrlGenerationService.CacheStats stats = minIOUrlGenerationService.getCacheStats();
            
            return ApiResponse.success(Map.of(
                "totalCached", stats.getTotalCached(),
                "validCount", stats.getValidCount(),
                "expiredCount", stats.getExpiredCount()
            ));
            
        } catch (Exception e) {
            logger.error("获取缓存统计失败", e);
            return ApiResponse.error("获取缓存统计失败: " + e.getMessage());
        }
    }
    
    /**
     * 清空 URL 缓存（仅 MinIO 存储）
     * DELETE /api/files/urls/cache
     */
    @DeleteMapping("/cache")
    public ApiResponse<String> clearCache() {
        try {
            if (minIOUrlGenerationService == null) {
                return ApiResponse.error("当前存储类型不支持URL缓存清理");
            }
            
            minIOUrlGenerationService.clearCache();
            
            logger.info("清空URL缓存成功");
            
            return ApiResponse.success("URL缓存已清空");
            
        } catch (Exception e) {
            logger.error("清空缓存失败", e);
            return ApiResponse.error("清空缓存失败: " + e.getMessage());
        }
    }
    
    /**
     * 批量 URL 请求对象
     */
    public static class BatchUrlRequest {
        private List<Long> fileIds;
        private int expirationSeconds = 3600; // 默认1小时
        
        public List<Long> getFileIds() {
            return fileIds;
        }
        
        public void setFileIds(List<Long> fileIds) {
            this.fileIds = fileIds;
        }
        
        public int getExpirationSeconds() {
            return expirationSeconds;
        }
        
        public void setExpirationSeconds(int expirationSeconds) {
            this.expirationSeconds = expirationSeconds;
        }
    }
}
